home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 3: Developer Tools / Linux Cubed Series 3 - Developer Tools.iso / utils / shell / dialog-0.000 / dialog-0 / dialog-0.6c / old / gpm-xterm.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-08-07  |  7.2 KB  |  302 lines

  1. /*
  2.  * gpm-xterm.c - pseudo client for non-Linux xterm only mouse support.
  3.  *               This code has been extracted from libgpm-0.18 and then
  4.  *               took its own way.
  5.  *
  6.  * Copyright (C) 1994   rubini@ipvvis.unipv.it (Alessandro Rubini)
  7.  * Copyright (C) 1994   Janne Kukonlehto
  8.  *
  9.  *   This program is free software; you can redistribute it and/or modify
  10.  *   it under the terms of the GNU General Public License as published by
  11.  *   the Free Software Foundation; either version 2 of the License, or
  12.  *   (at your option) any later version.
  13.  *
  14.  *   This program is distributed in the hope that it will be useful,
  15.  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
  16.  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17.  *   GNU General Public License for more details.
  18.  *
  19.  *   You should have received a copy of the GNU General Public License
  20.  *   along with this program; if not, write to the Free Software
  21.  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  22.  ********/
  23.  
  24.  
  25. #include <stdio.h>
  26. #include <stdlib.h>
  27. #include <unistd.h>        /* select(); */
  28. #include <sys/time.h>        /* timeval */
  29. #include <sys/types.h>        /* socket() */
  30.  
  31. #ifdef HAVE_NCURSES_H
  32. #include <ncurses.h>
  33. #else
  34. #include <curses.h>
  35. #endif
  36.  
  37. #include "gpm-xterm.h"
  38. #define RELEASE "0.97"
  39.  
  40. /******* This from liblow.c(libgpm) */
  41.  
  42. int gpm_flag = 0, gpm_tried = 0, gpm_fd = -1, gpm_hflag = 0;
  43. int gpm_zerobased = 0, gpm_visiblepointer = 0, gpm_morekeys = 0;
  44. struct timeval gpm_timeout =
  45. {10, 0};
  46.  
  47. Gpm_Handler *gpm_handler = NULL;
  48. void *gpm_data = NULL;
  49.  
  50. static int gpm_convert_event (char *mdata, Gpm_Event * ePtr);
  51.  
  52. /******* This from libcurses.c(libgpm) */
  53. int
  54. Gpm_Wgetch (WINDOW * win)
  55. {
  56.     int flag, result;
  57.     int fd = STDIN_FILENO;
  58.     static Gpm_Event ev;
  59.     static struct timeval to =
  60.     {0, 0}, tv1 =
  61.     {0, 0}, tv2;
  62.     static fd_set selSet;
  63.     static int prevchar = EOF, clicks = 0;
  64.     static char mdata[4];
  65.     int c;
  66.  
  67. #define GET(win) ((win) ? wgetch(win) : getch())
  68.  
  69. #define GET_TIME(tv) (gettimeofday(&tv, (struct timezone *)NULL))
  70. #define DIF_TIME(t1,t2) ((t2.tv_sec -t1.tv_sec) *1000+ \
  71.                          (t2.tv_usec-t1.tv_usec)/1000)
  72.  
  73.     if (!gpm_flag)
  74.     return GET (win);
  75.     if (gpm_morekeys && gpm_handler)
  76.     return (*gpm_handler) (&ev, gpm_data);
  77.  
  78.     gpm_hflag = 0;        /* not generated by handler (default) */
  79.  
  80.     if ((c = prevchar) != EOF) {    /* if ungetc() didn't suffice... */
  81.     prevchar = EOF;
  82.     return c;
  83.     }
  84.     while (1) {
  85.     do {
  86.         FD_ZERO (&selSet);
  87.         FD_SET (fd, &selSet);
  88.         gpm_timeout.tv_sec = SELECT_TIME;
  89.         flag = select (fd + 1, &selSet, (fd_set *) NULL, (fd_set *) NULL, &to);
  90.     }
  91.     while (!flag);
  92.  
  93.     if ((c = GET (win)) != 0x1b)
  94.         return c;
  95.  
  96.     /* escape: go on */
  97.     FD_ZERO (&selSet);
  98.     FD_SET (fd, &selSet);
  99.     if ((flag = select (fd + 1, &selSet, (fd_set *) NULL, (fd_set *) NULL, &to)) == 0)
  100.         return c;
  101.     if ((c = GET (win)) != '[') {
  102.         ungetc (c, stdin);
  103.         return 0x1B;
  104.     }
  105.     /* '[': go on */
  106.     FD_ZERO (&selSet);
  107.     FD_SET (fd, &selSet);
  108.     if ((flag = select (fd + 1, &selSet, (fd_set *) NULL, (fd_set *) NULL, &to)) == 0) {
  109.         ungetc (c, stdin);
  110.         return 0x1B;
  111.     }
  112.     if ((c = GET (win)) != 'M') {
  113.         ungetc (c, stdin);
  114.         prevchar = '[';
  115.         return 0x1B;
  116.     }
  117.     /* now, it surely is a mouse event */
  118.     for (c = 0; c < 3; c++)
  119.         mdata[c] = GET (win);
  120.     gpm_convert_event (mdata, &ev);
  121.  
  122.     if (gpm_handler && (result = (*gpm_handler) (&ev, gpm_data))) {
  123.         gpm_hflag = 1;
  124.         return result;
  125.     }
  126.     }                /* while(1) */
  127. }
  128.  
  129. /******* This from liblow.c(libgpm) */
  130. int
  131. Gpm_Open (Gpm_Connect * conn, int flag)
  132. {
  133.     char *tty;
  134.     int i;
  135.  
  136.     if ((tty = (char *) getenv ("TERM")) && !strncmp (tty, "xterm", 5)) {
  137.     if (gpm_tried)
  138.         return gpm_fd;    /* already open */
  139.     gpm_fd = -2;
  140.     GPM_XTERM_ON;
  141.     gpm_flag = 1;
  142.     return gpm_fd;
  143.     }
  144.     return -1;
  145. }
  146.  
  147. int
  148. Gpm_Close (void)
  149. {
  150.     if (gpm_fd == -2)        /* xterm */
  151.     GPM_XTERM_OFF;
  152.     gpm_tried = 0;
  153.     gpm_fd = -1;
  154.     return 0;
  155. }
  156.  
  157. int
  158. Gpm_Getc (FILE * f)
  159. {
  160. #define DELAY_MS 500        /* stolen form mc */
  161.     int flag, result;
  162.     static Gpm_Event ev;
  163.     int fd = fileno (f);
  164.     static int count;
  165.     static struct timeval to =
  166.     {0, DELAY_MS * 1000}, tv1 =
  167.     {0, 0}, tv2;
  168.     static fd_set selSet;
  169.     static int prevchar = EOF, clicks = 0;
  170.     static char mdata[4];
  171.     int c;
  172.  
  173.     /* Hmm... I must be sure it is unbuffered */
  174.     if (!(count++))
  175.     setvbuf (f, NULL, _IONBF, 0);
  176.  
  177.     if (!gpm_flag)
  178.     return fgetc (f);
  179.  
  180.     /* If the handler asked to provide more keys, give them back */
  181.     if (gpm_morekeys && gpm_handler)
  182.     return (*gpm_handler) (&ev, gpm_data);
  183.     gpm_hflag = 0;
  184.  
  185.     if ((c = prevchar) != EOF) {    /* if ungetc() didn't suffice... */
  186.     prevchar = EOF;
  187.     return c;
  188.     }
  189.     while (1) {
  190.     do {
  191.         FD_ZERO (&selSet);
  192.         FD_SET (fd, &selSet);
  193.         gpm_timeout.tv_sec = SELECT_TIME;
  194.         flag = select (fd + 1, &selSet, (fd_set *) NULL, (fd_set *) NULL, &to);
  195.     }
  196.     while (!flag);
  197.  
  198.     if ((c = fgetc (f)) != 0x1b)
  199.         return c;
  200.  
  201.     /* escape: go on */
  202.     FD_ZERO (&selSet);
  203.     FD_SET (fd, &selSet);
  204.     to.tv_usec = DELAY_MS * 1000;
  205.     if ((flag = select (fd + 1, &selSet, (fd_set *) NULL, (fd_set *) NULL, &to)) == 0)
  206.         return c;
  207.     if ((c = fgetc (f)) != '[') {
  208.         ungetc (c, stdin);
  209.         return 0x1B;
  210.     }
  211.     /* '[': go on */
  212.     FD_ZERO (&selSet);
  213.     FD_SET (fd, &selSet);
  214.     to.tv_usec = DELAY_MS * 1000;
  215.     if ((flag = select (fd + 1, &selSet, (fd_set *) NULL, (fd_set *) NULL, &to)) == 0) {
  216.         ungetc (c, f);
  217.         return 0x1B;
  218.     }
  219.     if ((c = fgetc (f)) != 'M') {
  220.         ungetc (c, f);
  221.         prevchar = '[';
  222.         return 0x1B;
  223.     }
  224.     /* now, it surely is a mouse event */
  225.     for (c = 0; c < 3; c++)
  226.         mdata[c] = fgetc (f);
  227.     gpm_convert_event (mdata, &ev);
  228.  
  229.     if (gpm_handler && (result = (*gpm_handler) (&ev, gpm_data))) {
  230.         gpm_hflag = 1;
  231.         return result;
  232.     }
  233.     }                /* while(1) */
  234. }
  235.  
  236. int
  237. Gpm_Repeat (int msec)
  238. {
  239.     struct timeval to =
  240.     {0, 0};
  241.     fd_set selSet;
  242.     int fd = STDIN_FILENO;
  243.  
  244.     to.tv_usec = msec * 1000;
  245.     FD_ZERO (&selSet);
  246.     FD_SET (fd, &selSet);
  247.     return (select (fd + 1, &selSet, (fd_set *) NULL, (fd_set *) NULL, &to) == 0);
  248. }
  249.  
  250. /*-------------------------------------------------------------------*/
  251. /* this is the real protocol conversion */
  252. static int
  253. gpm_convert_event (char *mdata, Gpm_Event * ePtr)
  254. {
  255.     static struct timeval tv1 =
  256.     {0, 0}, tv2;
  257.     static int clicks = 0;
  258.     int c;
  259.  
  260. #define GET_TIME(tv) (gettimeofday(&tv, (struct timezone *)NULL))
  261. #define DIF_TIME(t1,t2) ((t2.tv_sec -t1.tv_sec) *1000+ \
  262.                          (t2.tv_usec-t1.tv_usec)/1000)
  263.  
  264.  
  265.     /* Variable btn has following meaning: */
  266.     c = mdata[0] - 32;        /* 0="1-down", 1="2-down", 2="3-down", 3="up" */
  267.  
  268.     if (c == 3) {
  269.     ePtr->type = GPM_UP | (GPM_SINGLE << clicks);
  270.     ePtr->buttons = 0;
  271.     GET_TIME (tv1);
  272.     clicks = 0;
  273.     } else {
  274.     ePtr->type = GPM_DOWN;
  275.     GET_TIME (tv2);
  276.     if (tv1.tv_sec && (DIF_TIME (tv1, tv2) < 250)) {    /* 250ms for double click */
  277.         clicks++;
  278.         clicks %= 3;
  279.     } else
  280.         clicks = 0;
  281.  
  282.     switch (c) {
  283.     case 0:
  284.         ePtr->buttons |= GPM_B_LEFT;
  285.         break;
  286.     case 1:
  287.         ePtr->buttons |= GPM_B_MIDDLE;
  288.         break;
  289.     case 2:
  290.         ePtr->buttons |= GPM_B_RIGHT;
  291.         break;
  292.     default:        /* Nothing */
  293.         break;
  294.     }
  295.     }
  296.     /* Coordinates are 33-based */
  297.     /* Transform them to 1-based */
  298.     ePtr->x = mdata[1] - 32;
  299.     ePtr->y = mdata[2] - 32;
  300.     return 0;
  301. }
  302.